package cz.schovjan.proj.controllers;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;

import cz.schovjan.proj.dto.Band;
import cz.schovjan.proj.model.FiltrFormBean;
import cz.schovjan.proj.service.IBand;
import cz.schovjan.proj.service.IConcert;
import cz.schovjan.proj.service.IMember;
import cz.schovjan.proj.service.ISong;

/**
 * Kontroler pro editaci/detail kapely.
 * @author schovjan
 *
 */
@Controller
@RequestMapping("/band")
@SessionAttributes({"bands","band","user"}) //user se musi uvest taky, jinak se nepouzije
public class BandController extends Base {
	
	/** stranka s prehledem vsech kapel */
	private static final String BANDS = "bands";

	/** stranka s detailem kapely */
	private static final String BAND_DETAIL = "detailBand";	
	
	/** stranka s editaci clenu, pisni a koncertu */
	private static final String BAND_EDIT_MSC = "bandMemberSongConcert";	
	
	/** stranka s nahledem pdf kapel */
	private static final String PDF_DETAIL = "pdfDetail";
	
	/** Service pro kapely.	 */
	@Autowired
	private IBand bands;
	
	/** Service pro cleny.	 */
	@Autowired
	private IMember members;
	
	/** Service pro cleny.	 */
	@Autowired
	private ISong songs;
	
	/** Service pro koncerty.	 */
	@Autowired
	private IConcert concerts;
	
	@ModelAttribute("filtrFormBean")
	public FiltrFormBean createFiltrFormBean() {
		return new FiltrFormBean();
	}
	
	
	/////////////////
	//OBSLUZNE FUKNCE ------------------------------------------------------------
	/////////////////
	
	
	/**
	 * Vyber kapel z DB a zobrazeni ho v tabulce.
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/summary")
	public String summary(ModelMap model) {
		List<Band> list = bands.findAll();
		model.addAttribute("bands", list);
		model.addAttribute("bandsFiltr", list);
		
		return BANDS;
	}
	
	
	/**
	 * Filtrovani do roletky dle nazvu kapel.
	 * @param model
	 * @return
	 */
	@RequestMapping(method=RequestMethod.POST, value="/filtrSubmit")
	public String filtrSubmit(FiltrFormBean filtrFormBean, @ModelAttribute("bands") List<Band> bands, ModelMap model) {
		List<Band> bandsFiltr = new ArrayList<Band>();
		
		for (Band b : bands) {
			if (b.getName().toLowerCase().contains(filtrFormBean.getName().toLowerCase())) {
				bandsFiltr.add(b);
			}
		}
		model.addAttribute("bandsFiltr", bandsFiltr);
		
		return BANDS;
	}
	
	
	/**
	 * Prohlizeni kapely.
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/browse")
	public String detail(@RequestParam("id") int id, ModelMap model) {
		model.addAttribute("edit", false);
		model.addAttribute("band", bands.find(id));
		
		return BAND_DETAIL;
	}

	
	/**
	 * Editace kapely.
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/edit")
	public String edit(@RequestParam("id") int id, ModelMap model) {
		model.addAttribute("edit", true);
		model.addAttribute("band", bands.find(id));
		
		return BAND_DETAIL;
	}
	
	
	/**
	 * Editace �len� kapely.
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/editMembers")
	public String editMembers(@RequestParam("id") int id, ModelMap model) {
		model.addAttribute("editMembers", true);
		model.addAttribute("otherMembers", members.findOtherMembers(id));
		model.addAttribute("band", bands.find(id));
		
		return BAND_EDIT_MSC;
	}
	
	
	/**
	 * Editace repertoaru kapely.
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/editSongs")
	public String editSongs(@RequestParam("id") int id, ModelMap model) {
		model.addAttribute("editSongs", true);
		model.addAttribute("otherSongs", songs.findOtherSongs(id));
		model.addAttribute("band", bands.find(id));
		
		return BAND_EDIT_MSC;
	}
	
	
	/**
	 * Editace koncertu kapely.
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/editConcerts")
	public String editConcerts(@RequestParam("id") int id, ModelMap model) {
		model.addAttribute("editConcerts", true);
		model.addAttribute("otherConcerts", concerts.findOtherConcerts(id));
		model.addAttribute("band", bands.find(id));
		
		return BAND_EDIT_MSC;
	}
	
	
	/**
	 * Smazani kapely
	 * @param model
	 * @param id ID kapely ktera se maze
	 * @return
	 */
	@RequestMapping(value="/delete")
	public String delete(@RequestParam("id") int id, ModelMap model) {
		bands.delete(id);
		
		return "redirect:/band/summary";
	}
	
	
	/**
	 * Ulozeni zmen pri editaci kapely.
	 * @param band
	 * @param result
	 * @param model
	 * @return
	 */
	@RequestMapping(method=RequestMethod.POST, value="/bandSave")
	public String bandSave(@Valid @ModelAttribute("band") Band band, BindingResult result, ModelMap model) {
		model.addAttribute("edit", true);
		
		if (result.hasErrors()) {
			return BAND_DETAIL;
		}
		bands.save(band.getId(),
					band.getName(), 
					band.getEmail(), 
					band.getDescription(), 
					band.getCreation(), 
					band.getBreakup());
		model.addAttribute("message", MSG_BAND_SAVE);
		model.addAttribute("band", bands.find(band.getId()));
		model.addAttribute("otherMembers", members.findOtherMembers(band.getId()));
		
		return BAND_DETAIL;
	}
	

	/**
	 * Prida clena do kapely.
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/addMember")
	public String addMember(@ModelAttribute("band") Band band, @RequestParam("idM") int idM, ModelMap model) {
		bands.addMember(Integer.valueOf(band.getId()), Integer.valueOf(idM));
		
		return "redirect:/band/editMembers?id="+band.getId();
	}
	
	
	/**
	 * Odebere clena z kapely.
	 * @param band
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/removeMember")
	public String removeMember(@ModelAttribute("band") Band band, @RequestParam("idM") int idM, ModelMap model) {
		bands.removeMember(Integer.valueOf(band.getId()), Integer.valueOf(idM));
		
		return "redirect:/band/editMembers?id="+band.getId();
	}
	

	/**
	 * Prida pisen do repertoaru kapely.
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/addSong")
	public String addSong(@ModelAttribute("band") Band band, @RequestParam("idS") int idS, ModelMap model) {
		bands.addSong(Integer.valueOf(band.getId()), Integer.valueOf(idS));
		
		return "redirect:/band/editSongs?id="+band.getId();
	}
	
	
	/**
	 * Odebere pisen z repertoaru kapely.
	 * @param band
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/removeSong")
	public String removeSong(@ModelAttribute("band") Band band, @RequestParam("idS") int idS, ModelMap model) {
		bands.removeSong(Integer.valueOf(band.getId()), Integer.valueOf(idS));
		
		return "redirect:/band/editSongs?id="+band.getId();
	}

	
	/**
	 * Prida koncert ke kapele.
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/addConcert")
	public String addConcert(@ModelAttribute("band") Band band, @RequestParam("idC") int idC, ModelMap model) {
		bands.addConcert(Integer.valueOf(band.getId()), Integer.valueOf(idC));
		
		return "redirect:/band/editConcerts?id="+band.getId();
	}
	
	
	/**
	 * Odebere koncert od kapely.
	 * @param band
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/removeConcert")
	public String removeConcert(@ModelAttribute("band") Band band, @RequestParam("idC") int idC, ModelMap model) {
		bands.removeConcert(Integer.valueOf(band.getId()), Integer.valueOf(idC));
		
		return "redirect:/band/editConcerts?id="+band.getId();
	}

	
	/**
	 * Export do PDF.
	 * @throws FileNotFoundException 
	 */
	@RequestMapping(value="/exportToPdf")
	public String createPdf(@ModelAttribute("bands") List<Band> bands, ModelMap model) throws FileNotFoundException {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			Document doc = new Document();
			PdfWriter.getInstance(doc, baos);
			
			//pridani metadat
			doc.addAuthor("schovjan");
			doc.addTitle("DB Kapel");
			doc.addCreator("schovjan");

			//pridani dat
			doc.open();
			Paragraph p = null;
			p = new Paragraph();
			p.add("DB Kapel");
			
			for (Band b : bands) {
				p = new Paragraph();
				p.add(new Paragraph(String.format("%s - %s", b.getName(),b.getDescription())));
				doc.add(p);
			}
			
			doc.close();
			
			model.addAttribute("pdf", baos);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return PDF_DETAIL;
	}
	
}
